package com.aididi.filters;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

/**
 * @Auther: zx.xu
 * @Description:    zull路由拦截器
 */
@Component
@Slf4j
public class GatewayZuulFilter extends ZuulFilter{
    /**
     * 返回一个字符串代表过滤器的类型，在zuul中定义了四种不同生命周期的过滤器类型
     * pre：路由之前,可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等
     * routing：路由之时,用于构建发送给微服务的请求，并使用 Apache HttpClient 或 Netfilx Ribbon 请求微服务
     * post： 路由之后,可用来为响应添加标准的 HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等
     * error：发送错误调用,
     * @return
     */
    @Override
    public String filterType() {
        return "pre";
    }

    /**
     *  过滤的顺序
     * @return
     */
    @Override
    public int filterOrder() {
        return 0;
    }

    /**
     * 这里可以写逻辑判断，是否要过滤，本文true,永远过滤。
     * @return
     */
    @Override
    public boolean shouldFilter() {
        // 可通过一些业务逻辑判断是否要执行该过滤器。true执行，false不执行
        log.info("该请求将经过过滤器...");
        return true;
    }

    /**
     * 过滤器的具体逻辑。可用很复杂，包括查sql，nosql去判断该请求到底有没有权限访问
     * 实际开发中token应该从请求头中获取，该处只是为了方便演示效果
     * @return
     * @throws ZuulException
     */
    @Override
    public Object run() throws ZuulException {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();
        log.info(String.format(" %s>>> %s",request.getMethod(),request.getRequestURL().toString()));
        //这里可以配合jwt token，获取前端请求时的token
        Object accessToken = request.getParameter("token");
        if(null == accessToken){
            log.warn("token is empty");
            requestContext.setSendZuulResponse(false);
            //401：无权访问
            requestContext.setResponseStatusCode(401);
            requestContext.setResponseBody("token is empty");
            return null;
        }

        log.info("end");
        return null;
    }

}
